home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Interactive 7
/
PC World Interactive 7.iso
/
program
/
ctutor.exe
/
SOURCE
/
VC.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-05-15
|
15KB
|
350 lines
/* VC.C - Main Program - Visual Calculator */
/* Copyright (c) 1994 Coronado Enterprises */
/* */
/* This program will evaluate single value expressions in a manner */
/* similar to those evaluated by a hand-held calculator, hence */
/* its name, the Visual Calculator. */
/* */
/* Although this is a potentially useful program in its own right, */
/* it was originally written as an illustration of a rather large */
/* C program. It is especially useful because the student of C */
/* can run the program to determine its operating characteristics,*/
/* then study the code needed to perform the various operations. */
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <process.h>
#include "vc.h"
#include "video.h"
struct vars allvars[12]; /* this is the main variable storage */
int varinuse = 0; /* which variable is being used now */
char inline[200]; /* input line area */
int col; /* used for searching across the input */
int errcode; /* error code number */
int colerr; /* column where error occurred */
int printit = 0; /* 1 = print a transcript */
int ignore; /* 1 = ignore calculations for line */
extern char strngout[]; /* output message area */
FILE *prtfile; /* file pointers */
struct lines *top, *bot, *q, *p, *arrow, *trnsend;
/************************************************************ main */
/* This is the main control loop for the program. It initializes */
/* everything and reads statements until no errors are found. It */
/* continues reading until an F10 is detected in a subordinate */
/* function where control is returned to DOS */
void main(void)
{
top = bot = q = p = arrow = trnsend = NULL;
monitor(); /* initialize video attributes */
initdata(allvars); /* initialize all data */
bkgndvid(); /* display video background - double lines */
valusvid(allvars); /* display starting values of all variables */
strtrans("Welcome to the Visual Calculator - Version 2.00", 0);
transout();
do{
poscurs(23, 7);
printf(" input > ");
printf(" ");
do { /* repeat input until no errors */
readline(); /* get an input line */
errdis(" "); /* clear error msg */
parse(); /* parse the line */
if (errcode)
errout(); /* output error message */
} while (errcode);
if (ignore == 1)
strtrans(inline, 0); /* store comment in transcript */
else
strtrans(inline, 1); /* store "inline" in transcript */
transout();
} while (1); /* continuous loop */
}
/******************************************************** readline */
/* This function reads a line by inputting one character at a time */
/* and deciding what to do with it if it is a special character, */
/* or adding it to the input line if it is a special character. */
/* The routine takes care of such things as backspace, cursor */
/* movement and delete keys. The final result is a single line of */
/* text stored in the buffer "inline" and the line displayed on */
/* the monitor. */
void readline(void)
{
int index;
int c, temp;
int row = 23, col = 17;
if (errcode) { /* error recovery allow reenter */
index = colerr;
errcode = 0;
} else { /* normal input routine */
index = 0;
for (temp = 0 ; temp < 80 ; temp++)
inline[temp] = 0; /* clear input buffer */
}
poscurs(row, col + index); /* starting location of cursor */
do { /* repeat this loop until return hit */
while ((c = getch()) == EOF); /* get a keystroke */
if (c == 0) { /* a zero says a special key was hit */
/* get the key and act on it as needed */
int spec;
spec = getch(); /* this is the special code found */
switch (spec) {
case 59 : helpm(); /* F1 - Help math */
transout();
break;
case 60 : helps(); /* F2 - Help system */
transout();
break;
case 61 : if (printit) { /* F3 - Print on/off */
printit = 0; /* print off */
fprintf(prtfile, "%s\n\n", "Print off");
fclose(prtfile);
strcpy(strngout, "-----");
strngdis_help(1, 73);
} else {
prtfile = fopen("PRN", "w"); /* print on */
if (prtprblm()) {
errcode = 12; /* printer is not ready */
errout();
break;
}
printit = 1;
fprintf(prtfile, "%s\n", "Print On");
strcpy(strngout, "Print");
strngdis_val(1, 73);
}
break;
case 62 : /* F4 - Mark transcript */
arrow->marked = (arrow->marked ? 0 : 1);
transout();
break;
case 63 : fileout(); /* F5 - Store transcript*/
break;
case 64 : filein(); /* F6 - Retrieve trans */
errcode = 0;
break;
case 65 : /* F7 - */
break;
case 66 : /* F8 - */
break;
case 67 : /* F9 - Edit a line */
strcpy(inline, arrow->lineloc);
poscurs(23, 17);
printf("%s", inline);
break;
case 68 : poscurs(23, 17); /* F10 - Quit to DOS */
printf("Quit? (Y/N) ");
c = getch();
if ((c == 'Y') || (c == 'y')){
clrscrn();
exit(0);
}
poscurs(23, 17);
printf(" ");
break;
case 75 : if (index) { /* left arrow */
index = index -1; /* back up cursor */
}
break;
case 77 : if (index < 65) { /* right arrow */
if (inline[index] == 0) /* zero found */
inline[index] = ' '; /* blank over 0 */
index = index + 1; /* cursor forward */
}
break;
case 72 : movarrow(-1); /* up arrow */
break;
case 80 : movarrow(1); /* down arrow */
break;
case 73 : movarrow(-8); /* page up */
break;
case 81 : movarrow(8); /* page down */
break;
case 71 : movarrow(-1000); /* home */
break;
case 79 : movarrow(1000); /* end */
break;
case 83 : temp = index; /* delete key */
/* move all characters left one space */
while (inline[temp]) {
inline[temp] = inline[temp + 1];
putchar(inline[temp++]);
}
putchar(0); /* zero in last place */
break;
default : poscurs(15, 5);
printf(" S%3d", spec);
}
poscurs(row, col + index); /* put cursor in position */
}
else { /* normal letter or char hit */
int curr, next;
if (islower(c))
c = toupper(c); /* convert to upper case */
if ((c >= '\40') && (c <= '\176')) { /* printable char */
poscurs(row, col + index);
putchar(c);
next = inline[index];
inline[index++] = c;
curr = index;
while((next != 0) && (curr <= 65)) { /* move remainder */
temp = next; /* line right */
next = inline[curr];
inline[curr++] = temp;
putchar(temp);
}
} else {
if ((c == 8) && index) { /* backspace */
index--;
poscurs(row, col + index); /* back up cursor */
temp = index;
while (inline[temp]) {
inline[temp] = inline[temp + 1];
putchar(inline[temp++]);
}
putchar(0);
}
}
poscurs(row, col + index);
}
if (c == 3) exit(0); /* ctrl-break, out to DOS */
} while (c != 13); /* newline found, line input is complete */
}
/*********************************************************** parse */
/* This function does a lot of checking of the input line for */
/* logical errors in construction, then turns control over to the */
/* function "calcdata" for the actual calculations. */
void parse(void)
{
int index, parcol;
double newval;
char name[7];
varinuse = -1;
errcode = 0;
col = 0;
ignore = 1; /* ignore this line */
if (inline[0] == '#') { /* get list of variable names */
getnames();
return;
}
while (inline[col] == ' ') col++; /* ignore leading blanks */
if (inline[col] == '$') return; /* ignore a comment line */
if (inline[col] == 0) return; /* ignore a blank line */
ignore = 0; /* don't ignore this line */
name[0] = inline[col++]; /* find variable name */
index = 1;
while ((((inline[col] >= 'A') && (inline[col] <= 'Z')) ||
((inline[col] >= '0') && (inline[col] <= '9'))) &&
(index <= 5)) { /* continue var or function name */
name[index++] = inline[col++];
}
name[index] = 0; /* name found */
for (index = 0 ; index < 12 ; index++) {
if ((strcmp(name, allvars[index].varname)) == 0)
varinuse = index; /* variable name found */
}
if (varinuse < 0)
errchk(3); /* unknown variable name */
while (inline[col] == ' ')
col++; /* ignore leading blanks */
if (inline[col] == '=')
col++;
else
errchk(8); /* missing equal sign */
parcol = 0; /* now check for correct parenthesis matchup */
index = col;
do {
if (inline[col] == '(')
parcol++;
if (inline[col++] == ')')
parcol--;
if (parcol < 0)
errchk(1); /* paren count went negative */
} while (inline[col]);
if (parcol)
errchk(2); /* left over parentheses */
col = index;
calcdata(&newval); /* now go evaluate the full expression */
if (errcode == 0) { /* don't update value if error found */
allvars[varinuse].value = newval;
disnew(varinuse, allvars); /* display the changed value */
}
}
/********************************************************** errout */
/* This is the function that displays the blinking error message */
/* on the monitor. Note the extra errors for expansion of the */
/* table. */
void errout(void)
{
switch (errcode) {
case 1 : errdis("extra right parentheses ");
break;
case 2 : errdis("missing right parentheses");
break;
case 3 : errdis("unknown variable name ");
break;
case 4 : errdis("invalid math operator ");
break;
case 5 : errdis("negative value for SQRT ");
break;
case 6 : errdis("function not found ");
break;
case 7 : errdis("negative value for LOG ");
break;
case 8 : errdis("equal sign missing ");
break;
case 9 : errdis("invalid data field ");
break;
case 10 : errdis("division by zero ");
break;
case 11 : errdis("File doesn't exist ");
break;
case 12 : errdis("Printer not ready ");
break;
case 13 : errdis("Out of memory ");
break;
case 14 : errdis("Dash expected ");
break;
case 15 : errdis("Invalid format code ");
break;
case 16 : errdis("Neg value for FACTORIAL ");
break;
case 17 : errdis("Err 17 ");
break;
default : errdis("unknown error ");
poscurs(21, 70);
printf("%d", errcode);
}
poscurs(23, 12 + colerr);
}